package com.roncoo.education.common.core.tools;

import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.zip.*;

public class ZipUtils {

    /**
     * 压缩单个文件到ZIP文件
     *
     * @param sourceFile 要压缩的文件路径
     * @param zipFilePath 生成的ZIP文件路径
     * @throws IOException 如果发生I/O错误
     */
    public static void zipFile(File sourceFile, String zipFilePath) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(zipFilePath);
             ZipOutputStream zos = new ZipOutputStream(fos);
             FileInputStream fis = new FileInputStream(sourceFile)) {

                ZipEntry zipEntry = new ZipEntry(sourceFile.getName());
                zos.putNextEntry(zipEntry);

                byte[] buffer = new byte[1024];
                int length;
                while ((length = fis.read(buffer)) >= 0) {
                    zos.write(buffer, 0, length);
                }

                zos.closeEntry();
        }
    }

    /**
     * 压缩目录到ZIP文件
     *
     * @param sourceDirPath 要压缩的目录路径
     * @param zipFilePath 生成的ZIP文件路径
     * @throws IOException 如果发生I/O错误
     */
    public static void zipDirectory(String sourceDirPath, String zipFilePath) throws IOException {
        Path sourceDirPathPath = Paths.get(sourceDirPath);
        if (!Files.exists(sourceDirPathPath) || !Files.isDirectory(sourceDirPathPath)) {
            throw new IOException("Source directory does not exist: " + sourceDirPath);
        }

        try (FileOutputStream fos = new FileOutputStream(zipFilePath);
             ZipOutputStream zos = new ZipOutputStream(fos)) {

            Files.walkFileTree(sourceDirPathPath, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    Path targetFile = sourceDirPathPath.relativize(file);
                    ZipEntry zipEntry = new ZipEntry(targetFile.toString());
                    zos.putNextEntry(zipEntry);

                    Files.copy(file, zos);
                    zos.closeEntry();
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                    Path targetDir = sourceDirPathPath.relativize(dir);
                    ZipEntry zipEntry = new ZipEntry(targetDir.toString() + "/");
                    zos.putNextEntry(zipEntry);
                    zos.closeEntry();
                    return FileVisitResult.CONTINUE;
                }
            });
        }
    }

    public static void main(String[] args) {
        try {
            // 示例：压缩单个文件
            File sourceFile = new File("D:\\tmp\\output.jpg");
            String path = sourceFile.getParent();
            System.out.println("PATH="+path);
            //String zipFilePath = "D:\\tmp\\archive22.zip";
            String zipFilePath = path+File.separator+sourceFile.getName()+".zip";
            zipFile(sourceFile, zipFilePath);

            // 示例：压缩目录
            String sourceDirPath = "D:\\tmp\\education";
            zipFilePath = "D:\\tmp\\education\\longxian_archive.zip";
            zipDirectory(sourceDirPath, zipFilePath);

            System.out.println("压缩成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}